import { _decorator, Component, Button, Node, Sprite, Label, SpriteFrame, AudioSource } from 'cc';
import { Game } from '../core/Game';
import { Databus } from '../core/Databus';
import { ResourceManager } from '../framework/ResourceManager';
import { UserAttribute } from '../core/UserAttribute';
import { SendWebSocket } from '../websocket/SendWebSocket';
import { queryRobotUserList } from '../services/UserInfo';
import { UniformFunction } from '../platform/UniformFunction';
import { PlatformSetting } from '../platform/PlatformSetting';
import DataEventReport from '../platform/DataEventReport';
import { uniConfig } from '../config/UniConfig';
import { GameDataAdaptor } from '../game/GameDataAdaptor';
const { ccclass, property } = _decorator;

const databus = Databus.Instance();
@ccclass('MatchPage')
export class MatchPage extends Component {
  private webTestRoomId = '1123456789';
  private backButton: Button = null;
  private inviteFriendNode: Node = null;

  private eightBallTitle: Node = null;
  private nineBallTitle: Node = null;
  private snookerBallTitle: Node = null;
  private inviteFriendButton: Button = null;
  private oppoUserHeaderNode: Node = null;
  private oppoUserCommponent: Node = null;
  private hasLoadHeaderImage = false;
  private robotIndex = 0;

  private defaultHeaderSpriteFrame: SpriteFrame = null;
  private stage = 0; // 0 进入页面  1 匹配用户中/已发送分享 2 已匹配/好友已经到来 3 进入房间中
  private ticketTips = ''
  private heartBeatTime = 0;
  onLoad(): void {
    const oc = this.node.getChildByName('OperateController');
    this.inviteFriendNode = this.node.getChildByName('OperateController').getChildByName('InviteFriendButton');

    this.inviteFriendButton = oc.getChildByName('InviteFriendButton').getComponent(Button);
    this.backButton = this.node.getChildByName('BackButton').getComponent(Button);
    this.inviteFriendButton.node.on(Button.EventType.CLICK, this.inviteUserFriend, this);
    this.backButton.node.on(Button.EventType.CLICK, this.backPage, this);

    this.eightBallTitle = this.node.getChildByName('TopNavigation').getChildByName('EightBall');
    this.nineBallTitle = this.node.getChildByName('TopNavigation').getChildByName('NineBall');
    this.snookerBallTitle = this.node.getChildByName('TopNavigation').getChildByName('SnookerBall');

    this.oppoUserCommponent = this.node.getChildByName('OppoUserComponent');
    const userHeaderNode = this.node.getChildByName('OppoUserComponent').getChildByName('UserHeader');
    const userHeader = userHeaderNode.getComponent(Sprite);
    this.defaultHeaderSpriteFrame = userHeader.spriteFrame;
    this.ticketTips = "";
  }

  update(deltaTime: number) {
    this.updateSelfUserHeader();
    this.updateOppoUserHeader();
    this.updateTopNavigation();
    this.updateTicketTips();
    this.updateSocketetHeart();
  }
  start() {
    Game.Instance().setSelfUserAttribute(databus.selfInfo);
    ResourceManager.Instance().setSpriteFrame(ResourceManager.OppoUserHeaderImage, this.defaultHeaderSpriteFrame);
    Game.Instance().setOutlookAttribute(databus.outlook.tableName, databus.outlook.mainBallName, databus.outlook.roomName);
    Game.Instance().setSelfUserQiuGanName(databus.outlook.ganName);

    if (Game.Instance().battleCate.isFrientBattle()) {
      this.inviteFriendNode.active = true;
      this.oppoUserCommponent.active = false;
    } else {
      this.inviteFriendNode.active = false;
      this.oppoUserCommponent.active = true;
    }

    if (databus.launchData.roomId !== '') {
      this.joinRoom();
      databus.launchData.roomId = '';
      this.inviteFriendNode.active = false; // 加入方不需要邀请
      this.oppoUserCommponent.active = true;
    }
    if (!Game.Instance().battleCate.isFrientBattle()) {
      this.startMatchNetUser();
    }
    this.ticketTips = "";
  }
  public startMatchNetUser() {
    Game.Instance().setSelfUserAttribute(databus.selfInfo);
    Game.Instance().playUsers[0].prepared();
    Game.Instance().playUsers[1].prepared();
    Game.Instance().playUsers[1].robot();
    this.stage = 1;
    
    // 匹配对手 & 并设置对手信息
    const ua = this.matchOppoUser();
    const ext = ResourceManager.Instance().getImageExt(ua.avatarUrl);
    ResourceManager.Instance().loadImageSpriteFrame(
      ResourceManager.OppoUserHeaderImage, ua.avatarUrl, ext
    );
    const that = this;
    DataEventReport.Instance().reportComponentEvent(databus.sceneStack.currentPageName(), 'StartMatchNetUser');
    setTimeout(() => {
      // 有可能返回了，所以这里判断一下
      if (!databus.sceneStack.isMatchPage()) {
        return;
      }
      that.playUserMatched();
      that.stage = 2;
      Game.Instance().setOppoUserAttribute(ua);
      
      Game.Instance().playUsers[0].started();
      Game.Instance().playUsers[1].started();
      DataEventReport.Instance().reportComponentEvent(databus.sceneStack.currentPageName(), 'StartGame');
      this.ticketTips = `已扣除入场券${uniConfig.TicketCoinValue}`;
      GameDataAdaptor.Instance().updateUserGoldCoin(-uniConfig.TicketCoinValue);
      databus.sceneStack.toRoomPage();
      Game.Instance().playUsers[0].restartStepTime();
      Game.Instance().playUsers[1].restartStepTime();
      console.log('oppo user matched ', ua);
    }, 1000 + Math.random() * 5000);
  }

  public inviteUserFriend(button: Button) {
    if (PlatformSetting.isHTML5()) {
      Game.Instance().setRoomId(this.webTestRoomId);
    }
    this.heartBeatTime = Date.now();
    Game.Instance().setSelfUserAttribute(databus.selfInfo);
    Game.Instance().playUsers[0].started();
    Game.Instance().playUsers[1].human();
    this.stage = 1;

    new SendWebSocket().roomCreated(Game.Instance().playUsers[0]);

    new SendWebSocket().userStatus(Game.Instance().playUsers[0]);

    // 分享给好友
    new UniformFunction().shareToFriend(
      Game.Instance().roomId, Game.Instance().gameType.valueType()
    );
    this.oppoUserCommponent.active = true;
    this.inviteFriendNode.active = false;
    DataEventReport.Instance().reportComponentEvent(databus.sceneStack.currentPageName(), 'InviteUserFriend');
  }

  private updateSelfUserHeader() {
    const headSpriteFrame = ResourceManager.Instance().getImageSpriteFrame(ResourceManager.SelfUserHeaderImage);
    if (!this.hasLoadHeaderImage && headSpriteFrame) {
      const userHeader = this.node.getChildByName('SelfUserComponent').getChildByName('UserHeader').getComponent(Sprite);
      userHeader.spriteFrame = headSpriteFrame;
    
      // 更新昵称
      const userName = this.node.getChildByName('SelfUserComponent').getChildByName('UserName').getComponent(Label);
      userName.string = databus.selfInfo.showNickName();
    }
  }
  private updateOppoUserHeader() {
    if (this.stage === 2 || Game.Instance().battleCate.isFrientBattle()) {
      const headSpriteFrame = ResourceManager.Instance().getImageSpriteFrame(ResourceManager.OppoUserHeaderImage);
      if (headSpriteFrame) {
        if (this.oppoUserHeaderNode) this.oppoUserHeaderNode.active = false;
        const userHeaderNode = this.node.getChildByName('OppoUserComponent').getChildByName('UserHeader');
        userHeaderNode.active = true;
        const userHeader = userHeaderNode.getComponent(Sprite);
        userHeader.spriteFrame = headSpriteFrame;

        const userName = this.node.getChildByName('OppoUserComponent').getChildByName('UserName').getComponent(Label);
        userName.string = Game.Instance().getOppoUserName();
      }
      return ;
    }
    if (this.stage < 1) {
      return;
    }
    const name = `UserHeader${this.robotIndex}`;
    if (this.oppoUserHeaderNode) this.oppoUserHeaderNode.active = false;
    this.oppoUserHeaderNode = this.node.getChildByName('OppoUserComponent').getChildByName(name);
    this.oppoUserHeaderNode.active = true;
    this.robotIndex += 1;
    if (this.robotIndex >= 10) this.robotIndex = 0;
  }
  private updateTopNavigation() {
    this.eightBallTitle.active = false;
    this.nineBallTitle.active = false;
    this.snookerBallTitle.active = false;

    if (Game.Instance().gameType.isEightBall()) {
      this.eightBallTitle.active = true;
    } else if (Game.Instance().gameType.isNineBall()) {
      this.nineBallTitle.active = true;
    } else if (Game.Instance().gameType.isSnooker()) {
      this.snookerBallTitle.active = true;
    }
  }
  private matchOppoUser() {
    for (var i=0; i<databus.robots.length; i++) {
      if (databus.selfInfo.playLevel.canMatchBattle(databus.robots[i].playLevel.playLevel)) {
        queryRobotUserList(databus.selfInfo.userId, databus.selfInfo.playLevel.playLevel);
        return databus.robots[i];
      }
    }
    if (databus.robots.length > 0) {
      queryRobotUserList(databus.selfInfo.userId, databus.selfInfo.playLevel.playLevel);
      return databus.robots[0];
    }
    queryRobotUserList(databus.selfInfo.userId, databus.selfInfo.playLevel.playLevel);
    return UserAttribute.newDefaultUser();
  }
  private backPage(button: Button) {
    DataEventReport.Instance().reportComponentEvent(databus.sceneStack.currentPageName(), 'ReturnBack');
    databus.sceneStack.backScene();
  }

  private joinRoom() {
    Game.Instance().battleCate.frientBattle();
    Game.Instance().setRoomId(databus.launchData.roomId);
    Game.Instance().gameType.setValueType(databus.launchData.gameType);
    Game.Instance().playUsers[0].started();
    Game.Instance().playUsers[1].human();
    new SendWebSocket().userStatus(Game.Instance().playUsers[0]);
    this.stage = 1;
  }

  private playUserMatched(volume: number = 0.25) {
    const sound = this.node.getChildByName('SoundManager').getChildByName('UserMatched').getComponent(AudioSource);
    sound.volume = volume;
    sound.play();
  }

  private updateTicketTips() {
    if (this.ticketTips !== "") {
      this.node.getChildByName('TicketTips').getChildByName('Label').active = true;
      this.node.getChildByName('TicketTips').getChildByName('Label').getComponent(Label).string = this.ticketTips;
    } else {
      this.node.getChildByName('TicketTips').getChildByName('Label').active = false;
    }
  }

  private updateSocketetHeart() {
    if (!Game.Instance().battleCate.isFrientBattle()) {
      return;
    }
    if (this.stage !== 1) {return; }
    // 3秒发一次心跳，重新连接上服务器
    const mt = Date.now();
    if (mt - this.heartBeatTime > 3000) {
      this.heartBeatTime = mt;
      new SendWebSocket().heartRequst();
    }
  }
}